package com.syn.synold4s.service;

import android.annotation.SuppressLint;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.os.PowerManager;
import android.provider.Settings;
import android.util.Log;
import android.widget.RemoteViews;

import androidx.annotation.Nullable;
import androidx.core.app.NotificationCompat;

import com.gaoyi.basemodule.baseCallback.OnResultListener;
import com.gaoyi.basemodule.baseUtil.DateFormatUtil;
import com.gaoyi.basemodule.baseUtil.GsonUtil;
import com.gaoyi.basemodule.baseUtil.LanguageUtils;
import com.gaoyi.basemodule.baseconstant.SPName;
import com.google.gson.reflect.TypeToken;
import com.syn.synold4s.R;
import com.syn.synold4s.activity.MainActivity;
import com.syn.synold4s.bean.dto.AlertNotifyDto;
import com.syn.synold4s.bean.dto.GoogleMapBean;
import com.syn.synold4s.receiver.MqttNotifyReceiver;
import com.syn.synold4s.repository.MqttRepository;
import com.syn.synold4s.util.NotificationUtil;

import org.eclipse.paho.android.service.MqttAndroidClient;
import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken;
import org.eclipse.paho.client.mqttv3.MqttCallback;
import org.eclipse.paho.client.mqttv3.MqttClient;
import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.eclipse.paho.client.mqttv3.MqttMessage;
import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;

import java.util.Calendar;

public class MqttService extends Service {
    private static final String TAG = "MqttService";
    private final static String HUB_URL = "tcp://118.142.82.50:2883";
    private static String MQTT_CLIENT_ID;
    private static final String SOS_TOPIC = "foursPlatform/alarm/sos/";
    private static final String ALERT_TOPIC = "foursPlatform/alarm/";
    private MqttClient mqttClient;
    private MqttConnectOptions mOptions;
    private final static long sleep = 3000;
    private static boolean isRunning = true;
    private int i = 0;
    private Thread thread;
    private PowerManager.WakeLock wakeLock;
    private PowerManager powerManager;
    private Notification.Builder mChannelBuilder;
    private NotificationCompat.Builder mBuilder;
    private String mLang = LanguageUtils.MAP_LANG_CHINA;
    private String mCode;
    private MqttRepository mRepository;

    public static void stopMqtt() {
        isRunning = false;
    }

    private void screenOn() {
        boolean isScreenOn = powerManager.isInteractive();
        if (!isScreenOn) {
            PowerManager.WakeLock wl = powerManager.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP, "synAntiWandering:notificationLock");
            wl.acquire(3000);
        }
    }

    @Override
    public void onCreate() {
        super.onCreate();
        mRepository = new MqttRepository();
        initializeMqtt();
    }

    private Handler mHandler = new Handler(Looper.getMainLooper());

    private void initializeMqtt() {
        try {
            MQTT_CLIENT_ID = Settings.Secure.getString(getContentResolver(), Settings.Secure.ANDROID_ID);
            Log.i(TAG, "initializeMqtt: "+MQTT_CLIENT_ID);
            mqttClient = new MqttClient(HUB_URL, MQTT_CLIENT_ID, new MemoryPersistence()); // 使用内存存储
            mqttClient.setCallback(new MqttCallback() {
                @Override
                public void connectionLost(Throwable cause) {
//                    connectMqtt(mCode);
//                    Log.e(TAG, "connectionLost: ", cause);
//                    try {
//                        mqttClient.reconnect();
//                    } catch (MqttException e) {
//                        Log.e(TAG, "connectionLost: ", e);
//                    }
                    mHandler.postDelayed(() -> connectMqtt(mCode),5000);
                }

                @Override
                public void messageArrived(String topic, MqttMessage message) {
                    Log.i(TAG, "messageArrived: " + topic + "," + message);
                    try {
                        if (topic.startsWith(ALERT_TOPIC)) {
                            AlertNotifyDto bean = (AlertNotifyDto) GsonUtil.getInstance().fromJson(message.toString(), new TypeToken<AlertNotifyDto>() {
                            }.getType());
                            if (bean == null) {
                                return;
                            }
                            if (topic.startsWith(SOS_TOPIC)) {
                                getAddress(bean);
                            } else {
                                String title = mLang.equals(LanguageUtils.MAP_LANG_ENGLISH) ? "Alert Notification" : "警報通知";
                                if (bean.getAlertName() == null && bean.getReason() == null) {
                                    return;
                                }
                                showNotification(title, bean.getAlertName() + " - " + bean.getReason() + "\n" + DateFormatUtil.DateTimeToStr(bean.getAlertAt(), "dd-MM-yyyy HH:mm:ss"));
                            }
                        }
                    } catch (Exception e) {
                        Log.e(TAG, "messageArrived: ", e);
                    }
                    // 处理收到的消息
                }

                @Override
                public void deliveryComplete(IMqttDeliveryToken token) {
                    Log.d(TAG, "Message Delivered");
                }
            });
        } catch (MqttException e) {
            Log.e(TAG, "initializeMqtt: ", e);
        }

    }

    private void getAddress(AlertNotifyDto bean) {
        mRepository.getAddress(bean, mLang, new OnResultListener() {
            @Override
            public void onSuccess(Object apiResult) {
                AlertNotifyDto alertNotifyDto = (AlertNotifyDto) apiResult;
                Intent intent = new Intent();
                intent.setAction(MqttNotifyReceiver.MY_ACTION);
                intent.putExtra(MqttNotifyReceiver.TYPE, alertNotifyDto.getType());
                intent.putExtra(MqttNotifyReceiver.WEARER, alertNotifyDto.getName());
                intent.putExtra(MqttNotifyReceiver.TEL, alertNotifyDto.getPhone());
                intent.putExtra(MqttNotifyReceiver.ADDRESS, alertNotifyDto.getAddress());
                intent.putExtra(MqttNotifyReceiver.ALERT_TIME, alertNotifyDto.getAlertTime());
                sendBroadcast(intent);
            }

            @Override
            public void onFails(Exception e) {
            }
        }, new TypeToken<GoogleMapBean>() {
        }.getType());
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        LanguageUtils.getInstance().initResources(this);
        isRunning = true;
        if (wakeLock == null) {
            powerManager = (PowerManager) getSystemService(Context.POWER_SERVICE);
            wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "SSSS:CPUKeepRunning");
            wakeLock.setReferenceCounted(true);
            Calendar c = Calendar.getInstance();
            c.setTimeInMillis(System.currentTimeMillis());
            int hour = c.get(Calendar.HOUR_OF_DAY);
            if (hour >= 23 || hour <= 6) {
                wakeLock.acquire(5000);
            } else {
                wakeLock.acquire(300000);
            }
        }
        mLang = intent.getStringExtra(SPName.MAP_TYPE);
        mCode = intent.getStringExtra(SPName.PROJ_CODE);
        connectMqtt(mCode);
        if (thread == null) {
            thread = new Thread(runnableSend);
            thread.start();
        }
        return START_STICKY;
    }

    private final Runnable runnableSend = new Runnable() {
        @Override
        public void run() {
            while (isRunning) {
                try {
                    Thread.sleep(sleep);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                if (mqttClient == null) {
                    continue;
                }
                if (!mqttClient.isConnected()) {
//                    try {
                        connectMqtt(mCode);
//                        mqttClient.reconnect();
//                    } catch (MqttException e) {
//                        Log.e(TAG, "connectionLost: ", e);
//                    }
                }
            }
        }
    };


    private void connectMqtt(String code) {
        if (mOptions == null) {
            mOptions = new MqttConnectOptions();
            mOptions.setUserName("mqttUser");
            mOptions.setPassword("mqtt@1234".toCharArray());
            mOptions.setAutomaticReconnect(true);
            mOptions.setCleanSession(true); // 使用清理会话
            mOptions.setKeepAliveInterval(20);
            mOptions.setConnectionTimeout(10);
        }
        try {
            mqttClient.connect(mOptions);
            subscribeToTopic(new String[]{SOS_TOPIC + code.toLowerCase(), ALERT_TOPIC + code});
        } catch (MqttException e) {
            e.printStackTrace();
        }
    }

    private void subscribeToTopic(String[] topic) {
        try {
            mqttClient.subscribe(topic, new int[]{2, 2});
        } catch (MqttException e) {
            e.printStackTrace();
        }
    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }


    @Override
    public void onDestroy() {
        if (wakeLock != null) {
            if (wakeLock.isHeld()) {
                wakeLock.release();
                wakeLock = null;
            }
        }
        if (thread != null) {
            thread = null;
        }
        disconnectMqtt();
        super.onDestroy();
    }

    private void disconnectMqtt() {
        try {
            if (mqttClient != null) {
                mqttClient.disconnect();
                mqttClient = null;
                Log.d(TAG, "MQTT Disconnected");
            }
        } catch (MqttException e) {
            e.printStackTrace();
        }
    }

    /**
     * 发送通知
     */
    @SuppressLint("NotificationTrampoline")
    private void showNotification(String title, String info) {
        screenOn();
        i++;
        if (i > 11) {
            i = 1;
        }
        NotificationUtil.getInstance().getNotificationManager().cancel(i);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            if (mChannelBuilder == null) {
                NotificationChannel channel = NotificationUtil.getInstance().getChannel();
                NotificationUtil.getInstance().getNotificationManager().createNotificationChannel(channel);
                mChannelBuilder = NotificationUtil.getInstance().getNotification(this).setAutoCancel(true).setShowWhen(true).setVisibility(Notification.VISIBILITY_PUBLIC).setSmallIcon(R.drawable.notify_icon);
            }
            mChannelBuilder.setWhen(System.currentTimeMillis()).setContentText(info).setContentTitle(title).setContentIntent(createIntent(i)).setCustomContentView(getNotificationView(title, info)).setCustomHeadsUpContentView(getNotificationBigView(title, info)).setCustomBigContentView(getNotificationBigView(title, info));
            NotificationUtil.getInstance().getNotificationManager().notify(i, mChannelBuilder.build());
        } else {
            if (mBuilder == null) {
                mBuilder = NotificationUtil.getInstance().getNotificationCompat(this).setAutoCancel(true).setShowWhen(true).setVibrate(new long[]{100, 100, 200}).setSmallIcon(R.drawable.notify_icon).setPriority(Notification.PRIORITY_HIGH).setDefaults(Notification.DEFAULT_ALL);
            }
            mBuilder.setWhen(System.currentTimeMillis()).setContentText(info).setContentTitle(title).setContentIntent(createIntent(i)).setCustomContentView(getNotificationView(title, info)).setCustomHeadsUpContentView(getNotificationBigView(title, info)).setCustomBigContentView(getNotificationBigView(title, info));
            NotificationUtil.getInstance().getNotificationManager().notify(i, mBuilder.build());
        }
    }

    /**
     * 获取自定义的通知
     *
     * @return
     */
    private RemoteViews getNotificationView(String title, String info) {
        RemoteViews remoteViews = new RemoteViews(getPackageName(), R.layout.notification_item);
        setTextViewText(remoteViews, title, info);
        return remoteViews;
    }

    /**
     * 获取自定义的通知
     *
     * @return
     */
    private RemoteViews getNotificationBigView(String title, String info) {
        RemoteViews remoteViews = new RemoteViews(getPackageName(), R.layout.notification_big_item);
        setTextViewText(remoteViews, title, info);
        return remoteViews;
    }

    private void setTextViewText(RemoteViews remoteViews, String title, String info) {
        remoteViews.setTextViewText(R.id.tv_title, title);
        remoteViews.setTextViewText(R.id.tv_content, info);
    }


    /**
     * 发送广播
     *
     * @return
     */
    private PendingIntent createIntent(int num) {
        Intent intent = new Intent(this, MainActivity.class);
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
        int flags = PendingIntent.FLAG_CANCEL_CURRENT;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
            flags |= PendingIntent.FLAG_IMMUTABLE;
        }
        return PendingIntent.getActivity(this, num, intent, flags);
    }
}
